import logging
import os

from query.agent.eugene_data_agent import EugeneDataAgent
from query.infra.llm.llm_factory import LlmFactory

logger = logging.getLogger(__name__)


def openai_api_key() -> str | None:
    return os.environ.get("OPENAI_API_KEY")


def anthropic_api_key() -> str | None:
    return os.environ.get("ANTHROPIC_API_KEY")


def llm_provider() -> str:
    """Determine which LLM provider to use based on LLM_PROVIDER env var or available keys."""
    provider = os.environ.get("LLM_PROVIDER", "").lower()
    if provider in ("anthropic", "claude"):
        return "anthropic"
    if provider in ("openai", "gpt"):
        return "openai"
    # Auto-detect: prefer anthropic if key is available, fallback to openai
    if anthropic_api_key():
        return "anthropic"
    if openai_api_key():
        return "openai"
    raise ValueError(
        "No LLM provider configured. Set ANTHROPIC_API_KEY or OPENAI_API_KEY in your environment."
    )


def eugene_mcp_server_url() -> str:
    return os.environ["EUGENE_MCP_SERVER_URL"]


def llm_model():
    """Create the LLM model based on configured provider."""
    provider = llm_provider()
    if provider == "anthropic":
        key = anthropic_api_key()
        if not key:
            raise ValueError("ANTHROPIC_API_KEY is required when LLM_PROVIDER=anthropic")
        model_id = os.environ.get("ANTHROPIC_MODEL_ID", "claude-sonnet-4-20250514")
        logger.info(f"LLM provider: Anthropic ({model_id})")
        return LlmFactory.anthropic_model(anthropic_key=key, model_id=model_id)
    else:
        key = openai_api_key()
        if not key:
            raise ValueError("OPENAI_API_KEY is required when LLM_PROVIDER=openai")
        model_id = os.environ.get("OPENAI_MODEL_ID", "gpt-4.1-mini")
        logger.info(f"LLM provider: OpenAI ({model_id})")
        return LlmFactory.openai_model(openai_key=key, model_id=model_id)


def eugene_data_agent() -> EugeneDataAgent:
    return EugeneDataAgent(
        eugene_mcp_server_url=eugene_mcp_server_url(), model=llm_model()
    )
